"""
@name : 类的定义和使用
@author : wenyao
@projectname: sanchuanglianxi
"""
#类的定义
class A():
    pass

class B:  #在python2里面它属于经典类
    pass

class C(object):  #在python2里面属于新式类
    pass

#python2  没有接object  ---经典类  继承object属于新式类
#python3 默认继承object  都是新式类
#object是所有类的父类

# class Bus317(object):
#     #类属性
#     line = "317"
#     def run(self,flag):
#         print("bus317 run")
#         if flag == 0:
#             print("从a站到c站")
#         else:
#             print("从c站开到a站")
#
# print(id(Bus317))
# #实例化对象
# bus01 = Bus317()
# print(id(bus01))
# #Bus317 类对象
# #bus01  实例对象
#
# #获取属性和实例方法
# print(bus01.line)
# bus01.run(0)
#
# #获取类属性
# print(Bus317.line)
# ==========================================
##__init__
class Bus317(object):
    #类属性
    '''  this is Bus317 class'''
    line = "317"
    prod = "a"
    a = []
    def __init__(self, car_num, name):
        #实例属性
        self.car_num =car_num
        self.name = name
        self.line = "318"
        self.lst = []
    def run(self,flag):
        print("bus317 run")
        if flag == 0:
            print("从a站到c站")
        else:
            print("从c站开到a站")
#
bus02 = Bus317("湘A2312","老司机")
bus02.prod = "c"
print(bus02.prod)
bus03 = Bus317("湘A2312","老司机")
print(bus03.prod)
# print(bus02.name)
# print(bus02.line)
#print(Bus317.name) #获取不到
#实例查找属性 --实例空间 --》找不到就会去类空间
#实例创建时 会有个类对象指针
#类不能去实例空间
#
# bus03 = Bus317("湘A2312","老司机")
# print(bus03.name)
# bus04 = Bus317("湘A2312","老司机")
# print(id(bus03),id(bus04))
# bus03.a.append(1)
# bus04.a.append(2)
# print(bus04.a)
# print(bus03.a)
# bus03.lst.append(1)
# bus04.lst.append(2)
# print(bus03.lst)
# print(bus04.lst)

#总结
#类 就是方法和属性组合在一起
#对象是类的一个实体
#创建类的时候会有一个类的命名空间，存储类中定义的属性
#创建一个对象(实例)也会创建一个对象的命名空间，存放对象的属性
#obj.name  会先从自己的空间里找name， 找不到就去类中找，类中找不到会去父类找，最后找不到就抛出异常。

#类常用相关方法：
# print(Bus317.__name__) #输出类名
# print(Bus317.__doc__) #输出文档注释
# print(Bus317.__dict__) #类的字典属性、名称空间
# #############
# print(Bus317.__class__) #实例对应的类（新式类）
# print(bus03.__class__)
# a = 2
# print(a.__class__)
# print(a.__class__.__class__)
# print(object.__class__)
##################
# print("xxxxxxxxxxxxxxxxxxxxxxxxxxx")
# #a>b>c
# print(Bus317.__bases__) #类所有的父类构成的元组

#__new__方法
# class Bus317(object):
#     #类属性
#     '''  this is Bus317 class'''
#     line = "317"
#     a = []
#     def __init__(self, car_num, name):
#         print("init bus317")
#         #实例属性
#         self.car_num =car_num
#         self.name = name
#         self.line = "318"
#         self.lst = []
#     def __new__(cls, *args, **kwargs):
#         print("new instance create:",cls)
#         print(args, kwargs)
#         return object.__new__(cls)
#     def run(self,flag=0):
#         print("bus317 run")
#         if flag == 0:
#             print("从a站到c站")
#         else:
#             print("从c站开到a站")
#
# bus01 = Bus317("湘A2312","老司机")
# # print(bus01)
# bus02 = Bus317("湘A2312","老司机")
# print(id(bus01),id(bus02))

# class BusChildren(Bus317):
#     def __init__(self):
#         print("init BusChildren")
#
#     # def __new__(cls):
#     #     print("new children:",cls)
#     #     return super().__new__(cls)
#     #     return super().__new__(Bus317)
#
#     def run(self):
#         print("hello children")
#
# bus02 = BusChildren()
# bus02.run()
# print(bus02.__class__)

#单例模式
# class Bus317(object):
#     line="317"
#     a=0   #类对象 创建了a=0  第一执行初始化之后 a = 第一个生成的实例对象
#     def __init__(self,car_num,name):   #相当于构造函数，只要创建对象，就会运行
#         self.car_name=car_num
#         self.name = name
#         self.line="318"
#         self.lst=[]
#         print("创建对象")
#     def __new__(cls, *args, **kwargs):
#         #cls代表当前的类名
#         if Bus317.a!=0:
#             return Bus317.a
#         else:
#             Bus317.a=object.__new__(cls)
#             return Bus317.a    #object.new创建一个实例。
#     def run(self,flag):
#         print("bus317 run")
#         if flag==0:
#             print("从A站开往C站")
#         else:
#             print("从C站开往A站")
# #先执行__new__   再执行__init__
# bus02=Bus317("hsak","dsgg")
# bus01=Bus317("hsak","asggg")
# bus=Bus317("hak","ggg")
# #bus = bus02 = bus01 = Bus317("hsak","dsgg")
# # a = b =c  = 1
# print(id(bus02),id(bus01),id(bus))

#new总结
##实例方法、静态方法、类方法。
#__new__是在实例创建之前调用的，他的任务就是创建实例，它是个静态方法
#__init__是当前实例创建好之后，对对象属性进行初始化工作的时候运行的，它是个实例方法

#1、__new__至少要有一个参数cls(可以取别的名字), 代表当前类，此参数在python解释器运行的时候自动识别
#2、__new__必须返回实例化对象
#3、__init__ 的self参数 就是表示__new__返回的这个实例，__init__在__new__的基础上做一些初始化工作，__init__不需要返回
#4、子类里没有定义__new__ ,会去找父类的__new__方法构建实例
#5、新式类才有__new__
#6、如果实例化的instance和本身class 不一致，__init__不会执行。
#7、最好不要重写__new__

#迭代器  __iter__  __next__
#__iter__ 返回自身  return self
#__next__ 一直获取下一个值
#斐波那契数列迭代器












